#include <cctype>
#include <iostream>
#include <map>
#include <sstream>
#include <string>

//#define DEBUG

enum Token_value {
  NAME, 
  NUMBER,
  END,
  COMMA=',',
  LP = '(',
  RP = ')'
};


typedef std::pair<double, std::size_t> Info;
typedef std::pair<std::string, Info> MapPair;
typedef std::map<std::string, Info> Map;

std::istream* input;
Map table;
Token_value curr_tok;
double number_value;
std::string string_value;


void
error(const std::string& s)
{
  std::cerr << "ERROR: " << s << std::endl;
  exit(1);
}


Token_value
get_token()
{
  char ch;
  do
    {
      if (!input->get(ch))
	{
	  return curr_tok = END;
	}
    }
  while (ch != '\n' && isspace(ch));

#ifdef DEBUG
  std::cerr << "ch = " << ch << std::endl;
#endif

  switch (ch)
    {
    case ',':
    case '(':
    case ')':
      {
	return curr_tok = Token_value(ch);
      }
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '.':
      {
	input->putback(ch);
	*input >> number_value;

#ifdef DEBUG
	std::cerr << "got number " << number_value << std::endl;
	std::cerr << "return curr_tok = NUMBER" << std::endl;
#endif

	return curr_tok = NUMBER;
      }
    default:
      {
	if (isalpha(ch))
	  {
	    string_value = ch;
	    while (input->get(ch) && isalnum(ch))
	      {
		string_value.push_back(ch);
	      }

#ifdef DEBUG
	    std::cerr << "string_value = " << string_value << std::endl;
#endif
	    
	    input->putback(ch);
	    return curr_tok = NAME;
	  }
	error("bad token");
      }
    }
}

int
main(int argc, char* argv[])
{
  switch (argc)
    {
    case 1:
      {
	input = &std::cin;
	break;
      }
    case 2:
      {
	input = new std::istringstream(argv[1]);
	break;
      }
    default:
      error("too many arguments!");
    }

  while (*input)
    {
      get_token(); 
      if (curr_tok == END) 
	{
	  break;
	}
      else 
	{
	  if (curr_tok != LP)     error("expect '('");
	  get_token(); if (curr_tok != NAME)   error("expect NAME");
	  get_token(); if (curr_tok != COMMA)  error("expect COMMA");
	  get_token(); if (curr_tok != NUMBER) error("expect NUMBER");
	  get_token(); if (curr_tok != RP)     error("expect ')'");
	  Info& info = table[string_value];
	  info.first += number_value;
	  info.second++;
	}
    }

  for (Map::const_iterator it = table.begin(); it != table.end(); ++it)
    {
      MapPair mp = *it;

      const std::string& name = mp.first;
      double sum = mp.second.first;
      std::size_t count = mp.second.second;

      std::cout << name << " " << sum << " " << sum/count << std::endl;
    }

  if (input != &std::cin)
    {
      delete input;
    }

  return 0;
}
